package vashion.azeroth.core.common;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import vashion.azeroth.core.item.dao.OperateFlowDao;
import vashion.azeroth.core.pojo.common.OperateFlowDO;

/**
 * Created by tingting on 15/9/5.
 * 运营操作流水记录器
 */
@Aspect
public class OperateFlowAspect {

    private final static Logger log = LoggerFactory.getLogger(OperateFlowAspect.class);
    @Autowired
    private OperateFlowDao operateFlowDao;

    @Before(value = "@annotation(NeedOperateFlow)")
    public void recordOperateFlow(JoinPoint joinPoint) {
        try {
            Class clazz = joinPoint.getTarget().getClass();
            String argStr = constructArgumentsString(clazz, joinPoint.getArgs());
            String attributes = clazz.getName() + ";" + joinPoint.getSignature().getName() + ";" + argStr;
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            NeedOperateFlow logFlowAble = signature.getMethod().getAnnotation(NeedOperateFlow.class);
            log.info("operate flow log=" + attributes);
            OperateFlowDO operateFlowDO =
                    new OperateFlowDO(getInnerId(joinPoint, logFlowAble.operateIdArgLocation()), attributes, logFlowAble.operateFlowEnum().getType());
            operateFlowDao.save(operateFlowDO);
        } catch (Exception e) {
            log.error("LogFlowAspect.recordLogFlow,joinPoint=" + joinPoint, e);
        }
    }

    private long getInnerId(JoinPoint joinPoint, int operateIdLocation) {
        Object[] args = joinPoint.getArgs();
        if (null == args || args.length == 0 || args.length <= operateIdLocation) {
            return 0l;
        }
        Object operateObject = args[operateIdLocation];
        if (operateObject instanceof Long) {
            return (Long) operateObject;
        }
        return 0;
    }

    private String constructArgumentsString(Class clazz, Object... arguments) {
        StringBuffer buffer = new StringBuffer();
        for (Object object : arguments) {
            buffer.append(object + ",");
        }
        return buffer.toString();
    }

}
